

#include "stddef.h"
#include "gd32f30x_timer.h"
#include "contract.h"
#include "base.h"
#include "ClockAlarmer.h"
#include "bsp.h"

static void ClockAlarmer_ConfigPeak(uint32_t max_clock);

#define ALARMER_TIMER			TIMER5
#define ALARMER_TIMER_IRQn		TIMER5_IRQn
#define ALARMER_TIMER_CLK_ENABLE()  rcu_periph_clock_enable(RCU_TIMER5)
#define ALARMER_TIMER_CLK_FREQ()	rcu_clock_freq_get(CK_APB1)

#define ALARMER_TIMER_CLEAR_COUNTOR()	timer_counter_value_config(ALARMER_TIMER, 0)
#define ALARMER_TIMER_SET_COUNTOR_PEAK(cnt) 	do{TIMER_CAR(ALARMER_TIMER) = (uint32_t)cnt;}while(0)
#define ALARMER_TIMER_GET_COUNTOR_PEAK() 		TIMER_CAR(ALARMER_TIMER)

#define CLOCK_SOURCE_FREQUENCY 36000000

#define ERROR_RANGE	4


static volatile uint32_t AlarmCounter;
static volatile uint32_t AlarmCurrentCountTop;
static vfun_t alarm_fun;

#if 0
void TIMER5_IRQHandler(void)
{
   if(SET == timer_interrupt_flag_get(ALARMER_TIMER, TIMER_INT_UP))
    {
    	uint32_t peak;
		uint32_t count;
    	
		timer_interrupt_flag_clear(ALARMER_TIMER, TIMER_INT_UP);
        count = AlarmCounter;
        peak = AlarmCurrentCountTop;

        if(AlarmCounter > peak)
        {
			count -= peak;
		}
		else
		{
			count = 0;
		}
		
		if(count < ERROR_RANGE)/*误差1个卡时钟*/
		{	
			timer_interrupt_disable(ALARMER_TIMER, TIMER_INT_UP);
			timer_disable(ALARMER_TIMER);
			AlarmCounter = 0;
			if(alarm_fun != (vfun_t)0)
			{
				alarm_fun();
			}
		}
		else
		{
			AlarmCounter = count;
			ClockAlarmer_ConfigPeak(count);
		}		
    }
}
#endif 


void ClockAlarmer_Init(uint32_t frequency)
{
    timer_parameter_struct timer_initpara;
	uint32_t uclk;

	nvic_irq_enable(ALARMER_TIMER_IRQn, 2, 1);
   	ALARMER_TIMER_CLK_ENABLE();
	
    timer_deinit(ALARMER_TIMER);

	uclk = ALARMER_TIMER_CLK_FREQ();
    timer_initpara.prescaler         = (uclk / frequency) - 1;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 100;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV2;
    timer_init(ALARMER_TIMER, &timer_initpara);
	
	timer_auto_reload_shadow_disable(ALARMER_TIMER);
    timer_interrupt_enable(ALARMER_TIMER, TIMER_INT_UP);
}

void ClockAlarmer_SetCardClockFrequency(uint32_t frequency)
{
    uint16_t prescaler;
    prescaler = (ALARMER_TIMER_CLK_FREQ() / frequency) - 1;
	timer_prescaler_config(ALARMER_TIMER, prescaler, TIMER_PSC_RELOAD_NOW);
}

static void ClockAlarmer_ConfigPeak(uint32_t max_clock)
{
	uint32_t count;

	count = min(max_clock, 65535);
	AlarmCurrentCountTop = count;
	ALARMER_TIMER_SET_COUNTOR_PEAK((uint16_t)(count - 1));    
}

/*
	alarm_action为一个函数指针，当ClockCountor溢出时，该函数指针所指函数被执行
*/
void ClockAlarmer_Start(uint32_t clock, vfun_t alarm_action)
{	
	if(clock < ERROR_RANGE)
	{
		AlarmCounter = 0;
		if(alarm_action)
		{
			alarm_action();
		}
		return ;
	}
	AlarmCounter = clock;
    alarm_fun = alarm_action;
    
    ALARMER_TIMER_CLEAR_COUNTOR();
    ClockAlarmer_ConfigPeak(clock);
	timer_interrupt_enable(ALARMER_TIMER, TIMER_INT_UP);
	timer_enable(ALARMER_TIMER);
}

void ClockAlarmer_Stop(void)
{	
    timer_interrupt_disable(ALARMER_TIMER, TIMER_INT_UP);
    timer_disable(ALARMER_TIMER);
	ALARMER_TIMER_CLEAR_COUNTOR();

    alarm_fun = 0;
}


